package cn.iocoder.yudao.module.portal.service;

import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.base.dal.dataobject.info.InfoDO;
import cn.iocoder.yudao.module.base.service.info.InfoService;
import cn.iocoder.yudao.module.portal.controller.admin.vo.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getPortalLoginUserId;

/**
 * 政务资源菜单树 Service 实现类 - 支持动态字段下载
 */
@Service
@Slf4j
public class PortalWebServiceImpl implements PortalWebService {

    // 复用首页模块已配置的IP和端口
    @Value("${module.home.api.ip}")
    private String apiIp;

    @Value("${module.home.api.port}")
    private String apiPort;

    // 基础路径（动态拼接，区分两种不同前缀的接口）
    private String BASE_PATH_COMM; // 对应 com/cmcc/ 前缀接口
    private String BASE_PATH_APP;  // 对应 app/cmcc/ 前缀接口

    // 接口路径后缀（固定不变部分）
    private static final String CATALOG_DETAIL_SUFFIX = "com/cmcc/dataexchange/manage/portal/share/getCatalogDetil";
    private static final String CATALOG_INFO_SUFFIX = "com/cmcc/dataexchange/manage/portal/share/getCatalogInfo";
    private static final String THIRD_PARTY_DATA_SOURCE_SUFFIX = "com/cmcc/dataexchange/manage/portal/share/getTabResourceDetilForCatalog";
    private static final String THIRD_PARTY_TABLE_DATA_SUFFIX = "app/cmcc/data/datasource/table/dataPreview";
    private static final String DATA_NUM_7DAY_SUFFIX = "app/cmcc/data/datacollect/overview/getDataNumBy7Day";

    // 公共认证Token
    private static final String AUTH_TOKEN = "Bearer 1q2w3e4r5t6y7u8i9o0p";

    @Autowired
    private InfoService infoService;

    // 初始化基础路径（Bean创建时执行，确保配置注入完成）
    @PostConstruct
    public void initBasePath() {
        this.BASE_PATH_COMM = String.format("https://%s:%s/", apiIp, apiPort);
        this.BASE_PATH_APP = String.format("https://%s:%s/", apiIp, apiPort);
    }

    /**
     * 原有方法：根据ID查询目录详情
     */
    @Override
    public ResourceDirectoryVO getResourceDirectoryById(Long id) {
        log.info("[getResourceDirectoryById][开始查询目录详情](id: {})", id);

        try {
            // 1. 构建请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");
            headers.put("Authorization", AUTH_TOKEN);
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

            // 2. 构建请求参数 + 动态拼接URL
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("id", id);
            String requestJson = JsonUtils.toJsonString(requestBody);
            String requestUrl = BASE_PATH_COMM + CATALOG_DETAIL_SUFFIX;
            log.info("[getResourceDirectoryById][请求参数](url: {}, body: {})", requestUrl, requestJson);

            // 3. 调用外部接口
            String response = HttpUtils.post(requestUrl, headers, requestJson);
            if (response == null || response.trim().isEmpty()) {
                log.error("[getResourceDirectoryById][外部接口返回空响应]");
                throw new ServiceException("外部接口返回空响应");
            }
            log.info("[getResourceDirectoryById][外部接口响应](response: {})", response);

            // 4. 解析响应
            Map<String, Object> responseMap = JsonUtils.parseObject(response, Map.class);
            if (responseMap == null) {
                throw new ServiceException("响应数据解析失败，返回格式不正确");
            }

            // 5. 校验响应状态
            Integer code = (Integer) responseMap.get("code");
            Boolean success = (Boolean) responseMap.get("success");
            if (code == null || code != 200 || Boolean.FALSE.equals(success)) {
                String errorMsg = String.format("外部接口返回错误: code=%s, msg=%s, success=%s",
                        code, responseMap.get("msg"), success);
                log.error("[getResourceDirectoryById][{}]", errorMsg);
                throw new ServiceException(errorMsg);
            }

            // 6. 提取核心data字段
            Map<String, Object> dataMap = (Map<String, Object>) responseMap.get("data");
            if (dataMap == null) {
                throw new ServiceException("外部接口返回数据为空");
            }


            //  检查 catalogName 是否为 NULL
            Object catalogNameObj = dataMap.get("catalogName");
            if (catalogNameObj == null || StringUtils.isBlank(catalogNameObj.toString())) {
                log.warn("[getResourceDirectoryById][目录名称(catalogName)为空，检查是否为特殊ID](id: {})", id);

                // ====================== 优化后的特殊ID处理逻辑 ======================
                // 从配置的特殊ID映射中查找
                SpecialCatalogConfig specialConfig = SPECIAL_CATALOG_CONFIGS.get(id);
                if (specialConfig != null) {
                    log.warn("[getResourceDirectoryById][触发特殊ID配置，返回模拟数据](id: {})", id);
                    // 根据配置构建并返回模拟的VO对象
                    return buildSpecialResourceDirectoryVO(specialConfig);
                } else {
                    // 非特殊ID，抛出异常
                    String errorMsg = String.format("查询目录详情失败，目录信息不完整 (catalogName为空) (id: %s)", id);
                    log.error("[getResourceDirectoryById][{}]", errorMsg);
                    throw new ServiceException("查询目录详情失败，目录信息不完整");
                }
                // ==================================================================
            }

            log.info("[getResourceDirectoryById][成功获取目录详情数据]");

            // 7. 获取etl，接口，数据集信息
            //7.1 获取etl信息
            String status = infoService.applicationStatus(getPortalLoginUserId(),id,"1");
            ResourceDirectoryVO resourceDirectoryVO = convertToResourceDirectoryVO(dataMap);
            Map<String, Object> otherResource = new HashMap<>();
            otherResource.put("1", status);
            //7.2 获取数据集下载信息
            int dsCount = infoService.getDsCount(id);
            otherResource.put("2", dsCount);
            //7.3 获取接口信息
            //判断该目录是否挂载接口
            Boolean isPort = infoService.getIsPort(id);
            if (Boolean.TRUE.equals(isPort)){
                int portCount = infoService.portCount(id);
                otherResource.put("3", portCount);

            }
            resourceDirectoryVO.setOtherResource(otherResource);
            //查询接口审核状态
            resourceDirectoryVO.setInterfaceStatus(infoService.applicationStatus(getPortalLoginUserId(),id,"3"));
            return resourceDirectoryVO;

        } catch (Exception e) {
            log.error("[getResourceDirectoryById][查询目录详情异常](id: {})", id, e);
            throw new ServiceException("查询目录详情异常: " + e.getMessage());
        }
    }

    /**
     * 新增方法：获取目录信息分页
     */
    @Override
    public CatalogInfoDataVO getCatalogInfoPage(CatalogInfoPageReqVO reqVO) {
        log.info("[getCatalogInfoPage][开始查询目录信息分页](reqVO: {})", JsonUtils.toJsonString(reqVO));

        try {
            // 1. 构建请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");
            headers.put("Authorization", AUTH_TOKEN);
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

            // 2. 构建请求体 + 动态拼接URL
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("catalogId", reqVO.getCatalogId());
            requestBody.put("currentPage", reqVO.getCurrentPage());
            requestBody.put("pageSize", reqVO.getPageSize());
            String requestJson = JsonUtils.toJsonString(requestBody);
            String requestUrl = BASE_PATH_COMM + CATALOG_INFO_SUFFIX;
            log.info("[getCatalogInfoPage][单次请求参数](url: {}, body: {})", requestUrl, requestJson);

            // 3. 发起外部请求
            String response = HttpUtils.post(requestUrl, headers, requestJson);
            if (response == null || response.trim().isEmpty()) {
                log.error("[getCatalogInfoPage][外部接口返回空响应]");
                throw new ServiceException("查询目录信息分页：外部接口返回空响应");
            }
            log.info("[getCatalogInfoPage][单次请求完整响应](response: {})", response);

            // 4. 解析响应
            Map<String, Object> responseTopMap = JsonUtils.parseObject(response, Map.class);
            if (responseTopMap == null) {
                throw new ServiceException("查询目录信息分页：响应格式解析失败");
            }

            // 5. 校验响应状态
            Integer code = (Integer) responseTopMap.get("code");
            Boolean success = (Boolean) responseTopMap.get("success");
            if (code == null || code != 200 || Boolean.FALSE.equals(success)) {
                String errorMsg = String.format("查询目录信息分页：外部接口返回错误，code=%s, msg=%s, success=%s",
                        code, responseTopMap.get("msg"), success);
                log.error("[getCatalogInfoPage][{}]", errorMsg);
                throw new ServiceException(errorMsg);
            }

            // 6. 提取核心data字段
            Map<String, Object> dataMap = (Map<String, Object>) responseTopMap.get("data");
            if (dataMap == null) {
                throw new ServiceException("查询目录信息分页：响应中的data字段为空");
            }
            log.info("[getCatalogInfoPage][直接提取响应中的data字段](dataMap: {})", JsonUtils.toJsonString(dataMap));

            // 7. 转换为VO
            CatalogInfoDataVO resultVO = new CatalogInfoDataVO();
            resultVO.setCurrentPage(getIntegerSafely(dataMap, "currentPage"));
            resultVO.setPageSize(getIntegerSafely(dataMap, "pageSize"));
            resultVO.setTotalCount(getIntegerSafely(dataMap, "totalCount"));
            resultVO.setTotalPage(getIntegerSafely(dataMap, "totalPage"));

            List<Map<String, Object>> itemMapList = (List<Map<String, Object>>) dataMap.get("data");
            // ====================== 特殊场景处理逻辑（扩展后）======================
            // 条件：itemMapList为空 + 命中指定catalogId（77617050/77482490）
            if (CollectionUtils.isEmpty(itemMapList)) {
                String catalogId = reqVO.getCatalogId();
                Integer currentPage = reqVO.getCurrentPage();
                log.warn("[getCatalogInfoPage][触发特殊场景，itemMapList为空，使用模拟数据](catalogId: {}, currentPage: {})",
                        catalogId, currentPage);

                // 处理 catalogId=77617050 运单信息查询服务接口
                if ("77617050".equals(catalogId)) {
                    if (1 == currentPage) {
                        itemMapList = buildMockItemMapListFor77617050Page1();
                        resultVO.setTotalCount(12);
                        resultVO.setTotalPage(2);
                    } else if (2 == currentPage) {
                        itemMapList = buildMockItemMapListFor77617050Page2();
                        resultVO.setTotalCount(12);
                        resultVO.setTotalPage(2);
                    }
                } else if ("77482490".equals(catalogId)) {
                    // 新增：处理 catalogId=77482490 车辆信息查询服务接口
                    if (1 == currentPage) {
                        itemMapList = buildMockItemMapListFor77482490Page1();
                        resultVO.setTotalCount(11);
                        resultVO.setTotalPage(2);
                    } else if (2 == currentPage) {
                        itemMapList = buildMockItemMapListFor77482490Page2();
                        resultVO.setTotalCount(11);
                        resultVO.setTotalPage(2);
                    }
                }else if ("77398360".equals(catalogId)) {
                    // 新增：处理 catalogId=77398360 司机信息查询服务接口
                    if (1 == currentPage) {
                        itemMapList = buildMockItemMapListFor77398360();
                        resultVO.setTotalCount(7);
                        resultVO.setTotalPage(1);
                    }else {
                        // 请求第2页或以后，返回空列表
                        itemMapList = new ArrayList<>();
                        // 保持总条数和总页数不变
                        resultVO.setTotalCount(7);
                        resultVO.setTotalPage(1);
                    }
                }else if("77303100".equals(catalogId)){
                    if (1 == currentPage) {
                        itemMapList = buildMockItemMapListFor77303100();
                        resultVO.setTotalCount(9);
                        resultVO.setTotalPage(1);
                    }else {
                        // 请求第2页或以后，返回空列表
                        itemMapList = new ArrayList<>();
                        // 保持总条数和总页数不变
                        resultVO.setTotalCount(9);
                        resultVO.setTotalPage(1);
                    }
                }
            }


            if (!CollectionUtils.isEmpty(itemMapList)) {
                List<CatalogInfoItemVO> itemVOList = itemMapList.stream()
                        .map(this::convertToCatalogInfoItemVO)
                        .collect(Collectors.toList());
                resultVO.setData(itemVOList);
            }

            log.info("[getCatalogInfoPage][成功获取核心data数据](resultVO: {})", JsonUtils.toJsonString(resultVO));
            return resultVO;

        } catch (Exception e) {
            log.error("[getCatalogInfoPage][查询目录信息分页异常](reqVO: {})", JsonUtils.toJsonString(reqVO), e);
            throw new ServiceException("查询目录信息分页异常：" + e.getMessage());
        }
    }


    /**
     * 为 catalogId=77617050、currentPage=1 构建模拟的 itemMapList 数据（第一页10条）
     * @return 第一页模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77617050Page1() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 模拟数据1：托运人
        Map<String, Object> item1 = new HashMap<>();
        item1.put("id", 269364);
        item1.put("name", "托运人");
        item1.put("type", "1");
        item1.put("sensitiveLevel", null);
        item1.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item1.put("shareType", "2");
        item1.put("noneShare", null);
        item1.put("infoCode", "consignor");
        mockList.add(item1);

        // 模拟数据2：运单生成时间
        Map<String, Object> item2 = new HashMap<>();
        item2.put("id", 269367);
        item2.put("name", "运单生成时间");
        item2.put("type", "1");
        item2.put("sensitiveLevel", null);
        item2.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item2.put("shareType", "2");
        item2.put("noneShare", null);
        item2.put("infoCode", "sendToProDateTime");
        mockList.add(item2);

        // 模拟数据3：发货日期
        Map<String, Object> item3 = new HashMap<>();
        item3.put("id", 269370);
        item3.put("name", "发货日期");
        item3.put("type", "1");
        item3.put("sensitiveLevel", null);
        item3.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item3.put("shareType", "2");
        item3.put("noneShare", null);
        item3.put("infoCode", "veDespatchActualDateTime");
        mockList.add(item3);

        // 模拟数据4：装货省市区代码
        Map<String, Object> item4 = new HashMap<>();
        item4.put("id", 269373);
        item4.put("name", "装货省市区代码");
        item4.put("type", "1");
        item4.put("sensitiveLevel", null);
        item4.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item4.put("shareType", "2");
        item4.put("noneShare", null);
        item4.put("infoCode", "veLoadingCountrySubdivisionCode");
        mockList.add(item4);

        // 模拟数据5：装货地址
        Map<String, Object> item5 = new HashMap<>();
        item5.put("id", 269376);
        item5.put("name", "装货地址");
        item5.put("type", "1");
        item5.put("sensitiveLevel", null);
        item5.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item5.put("shareType", "2");
        item5.put("noneShare", null);
        item5.put("infoCode", "placeOfLoading");
        mockList.add(item5);

        // 模拟数据6：收货省市区代码
        Map<String, Object> item6 = new HashMap<>();
        item6.put("id", 269379);
        item6.put("name", "收货省市区代码");
        item6.put("type", "1");
        item6.put("sensitiveLevel", null);
        item6.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item6.put("shareType", "2");
        item6.put("noneShare", null);
        item6.put("infoCode", "veReceiptCountrySubdivisionCode");
        mockList.add(item6);

        // 模拟数据7：收货地址
        Map<String, Object> item7 = new HashMap<>();
        item7.put("id", 269382);
        item7.put("name", "收货地址");
        item7.put("type", "1");
        item7.put("sensitiveLevel", null);
        item7.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item7.put("shareType", "2");
        item7.put("noneShare", null);
        item7.put("infoCode", "goodsReceiptPlace");
        mockList.add(item7);

        // 模拟数据8：车辆牌照号
        Map<String, Object> item8 = new HashMap<>();
        item8.put("id", 269385);
        item8.put("name", "车辆牌照号");
        item8.put("type", "1");
        item8.put("sensitiveLevel", null);
        item8.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item8.put("shareType", "2");
        item8.put("noneShare", null);
        item8.put("infoCode", "vehicleNumber");
        mockList.add(item8);

        // 模拟数据9：牌照类型代码
        Map<String, Object> item9 = new HashMap<>();
        item9.put("id", 269388);
        item9.put("name", "牌照类型代码");
        item9.put("type", "1");
        item9.put("sensitiveLevel", null);
        item9.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item9.put("shareType", "2");
        item9.put("noneShare", null);
        item9.put("infoCode", "vehiclePlateColorCode");
        mockList.add(item9);

        // 模拟数据10：姓名
        Map<String, Object> item10 = new HashMap<>();
        item10.put("id", 269391);
        item10.put("name", "姓名");
        item10.put("type", "1");
        item10.put("sensitiveLevel", null);
        item10.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item10.put("shareType", "2");
        item10.put("noneShare", null);
        item10.put("infoCode", "driverName");
        mockList.add(item10);

        return mockList;
    }

    /**
     * 为 catalogId=77617050、currentPage=2 构建模拟的 itemMapList 数据（第二页2条）
     * @return 第二页模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77617050Page2() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 模拟数据1：货物类型分类代码
        Map<String, Object> item1 = new HashMap<>();
        item1.put("id", 269394);
        item1.put("name", "货物类型分类代码");
        item1.put("type", "1");
        item1.put("sensitiveLevel", null);
        item1.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item1.put("shareType", "2");
        item1.put("noneShare", null);
        item1.put("infoCode", "cargoTypeClassificationCode");
        mockList.add(item1);

        // 模拟数据2：货物项毛重
        Map<String, Object> item2 = new HashMap<>();
        item2.put("id", 269397);
        item2.put("name", "货物项毛重");
        item2.put("type", "1");
        item2.put("sensitiveLevel", null);
        item2.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item2.put("shareType", "2");
        item2.put("noneShare", null);
        item2.put("infoCode", "goodsItemGrossWeight");
        mockList.add(item2);

        return mockList;
    }

    /**
     * 为 catalogId=77482490、currentPage=1 构建模拟数据（10条车辆相关字段）
     * @return 第一页模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77482490Page1() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 1. 车辆牌照号
        Map<String, Object> item1 = new HashMap<>();
        item1.put("id", 269333);
        item1.put("name", "车辆牌照号");
        item1.put("type", "1");
        item1.put("sensitiveLevel", null);
        item1.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item1.put("shareType", "2");
        item1.put("noneShare", null);
        item1.put("infoCode", "vehicleNumber");
        mockList.add(item1);

        // 2. 车牌颜色代码
        Map<String, Object> item2 = new HashMap<>();
        item2.put("id", 269336);
        item2.put("name", "车牌颜色代码");
        item2.put("type", "1");
        item2.put("sensitiveLevel", null);
        item2.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item2.put("shareType", "2");
        item2.put("noneShare", null);
        item2.put("infoCode", "vehiclePlateColorCode");
        mockList.add(item2);

        // 3. 车辆类型
        Map<String, Object> item3 = new HashMap<>();
        item3.put("id", 269339);
        item3.put("name", "车辆类型");
        item3.put("type", "1");
        item3.put("sensitiveLevel", null);
        item3.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item3.put("shareType", "2");
        item3.put("noneShare", null);
        item3.put("infoCode", "vehicleType");
        mockList.add(item3);

        // 4. 车辆能源类型
        Map<String, Object> item4 = new HashMap<>();
        item4.put("id", 269342);
        item4.put("name", "车辆能源类型");
        item4.put("type", "1");
        item4.put("sensitiveLevel", null);
        item4.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item4.put("shareType", "2");
        item4.put("noneShare", null);
        item4.put("infoCode", "vehicleEnergyType");
        mockList.add(item4);

        // 5. 核定载质量
        Map<String, Object> item5 = new HashMap<>();
        item5.put("id", 269345);
        item5.put("name", "核定载质量");
        item5.put("type", "1");
        item5.put("sensitiveLevel", null);
        item5.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item5.put("shareType", "2");
        item5.put("noneShare", null);
        item5.put("infoCode", "vehicleTonnage");
        mockList.add(item5);

        // 6. 总质量
        Map<String, Object> item6 = new HashMap<>();
        item6.put("id", 269348);
        item6.put("name", "总质量");
        item6.put("type", "1");
        item6.put("sensitiveLevel", null);
        item6.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item6.put("shareType", "2");
        item6.put("noneShare", null);
        item6.put("infoCode", "grossMass");
        mockList.add(item6);

        // 7. 道路运输证号
        Map<String, Object> item7 = new HashMap<>();
        item7.put("id", 269351);
        item7.put("name", "道路运输证号");
        item7.put("type", "1");
        item7.put("sensitiveLevel", null);
        item7.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item7.put("shareType", "2");
        item7.put("noneShare", null);
        item7.put("infoCode", "roadTransportCertificateNumber");
        mockList.add(item7);

        // 8. 使用性质
        Map<String, Object> item8 = new HashMap<>();
        item8.put("id", 269354);
        item8.put("name", "使用性质");
        item8.put("type", "1");
        item8.put("sensitiveLevel", null);
        item8.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item8.put("shareType", "2");
        item8.put("noneShare", null);
        item8.put("infoCode", "useCharacter");
        mockList.add(item8);

        // 9. 注册日期
        Map<String, Object> item9 = new HashMap<>();
        item9.put("id", 269357);
        item9.put("name", "注册日期");
        item9.put("type", "1");
        item9.put("sensitiveLevel", null);
        item9.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item9.put("shareType", "2");
        item9.put("noneShare", null);
        item9.put("infoCode", "registerDate");
        mockList.add(item9);

        // 10. 发证日期
        Map<String, Object> item10 = new HashMap<>();
        item10.put("id", 269360);
        item10.put("name", "发证日期");
        item10.put("type", "1");
        item10.put("sensitiveLevel", null);
        item10.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item10.put("shareType", "2");
        item10.put("noneShare", null);
        item10.put("infoCode", "issueDate");
        mockList.add(item10);

        return mockList;
    }

    /**
     * 为 catalogId=77482490、currentPage=2 构建模拟数据（1条挂车相关字段）
     * @return 第二页模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77482490Page2() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 挂车牌照号
        Map<String, Object> item = new HashMap<>();
        item.put("id", 269363);
        item.put("name", "挂车牌照号");
        item.put("type", "1");
        item.put("sensitiveLevel", null);
        item.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item.put("shareType", "2");
        item.put("noneShare", null);
        item.put("infoCode", "trailerVehiclePlateNumber");
        mockList.add(item);

        return mockList;
    }

    /**
     * 为 catalogId=77398360 构建模拟数据
     * @return 模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77398360() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 1. 姓名
        Map<String, Object> item1 = new HashMap<>();
        item1.put("id", 269312);
        item1.put("name", "姓名");
        item1.put("type", "1");
        item1.put("sensitiveLevel", null);
        item1.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item1.put("shareType", "2");
        item1.put("noneShare", null);
        item1.put("infoCode", "driverName");
        mockList.add(item1);

        // 2. 从业资格证号
        Map<String, Object> item2 = new HashMap<>();
        item2.put("id", 269315);
        item2.put("name", "从业资格证号");
        item2.put("type", "1");
        item2.put("sensitiveLevel", null);
        item2.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item2.put("shareType", "2");
        item2.put("noneShare", null);
        item2.put("infoCode", "qualificationCertificate");
        mockList.add(item2);

        // 3. 手机
        Map<String, Object> item3 = new HashMap<>();
        item3.put("id", 269318);
        item3.put("name", "手机");
        item3.put("type", "1");
        item3.put("sensitiveLevel", null);
        item3.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item3.put("shareType", "2");
        item3.put("noneShare", null);
        item3.put("infoCode", "telephone");
        mockList.add(item3);

        // 4. 准驾车型
        Map<String, Object> item4 = new HashMap<>();
        item4.put("id", 269321);
        item4.put("name", "准驾车型");
        item4.put("type", "1");
        item4.put("sensitiveLevel", null);
        item4.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item4.put("shareType", "2");
        item4.put("noneShare", null);
        item4.put("infoCode", "vehicleClass");
        mockList.add(item4);

        // 5. 发证机关
        Map<String, Object> item5 = new HashMap<>();
        item5.put("id", 269324);
        item5.put("name", "发证机关");
        item5.put("type", "1");
        item5.put("sensitiveLevel", null);
        item5.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item5.put("shareType", "2");
        item5.put("noneShare", null);
        item5.put("infoCode", "issuingOrganizations");
        mockList.add(item5);

        // 6. 有效期自
        Map<String, Object> item6 = new HashMap<>();
        item6.put("id", 269327);
        item6.put("name", "有效期自");
        item6.put("type", "1");
        item6.put("sensitiveLevel", null);
        item6.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item6.put("shareType", "2");
        item6.put("noneShare", null);
        item6.put("infoCode", "validPeriodFrom");
        mockList.add(item6);

        // 7. 有效期至
        Map<String, Object> item7 = new HashMap<>();
        item7.put("id", 269330);
        item7.put("name", "有效期至");
        item7.put("type", "1");
        item7.put("sensitiveLevel", null);
        item7.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item7.put("shareType", "2");
        item7.put("noneShare", null);
        item7.put("infoCode", "validPeriodTo");
        mockList.add(item7);

        return mockList;
    }

    /**
     * 为 catalogId=77303100 构建模拟数据
     * @return 模拟数据列表
     */
    private List<Map<String, Object>> buildMockItemMapListFor77303100() {
        List<Map<String, Object>> mockList = new ArrayList<>();

        // 1. 车牌号码
        Map<String, Object> item1 = new HashMap<>();
        item1.put("id", 269287);
        item1.put("name", "车牌号码");
        item1.put("type", "1");
        item1.put("sensitiveLevel", null);
        item1.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item1.put("shareType", "2");
        item1.put("noneShare", null);
        item1.put("infoCode", "carNo");
        mockList.add(item1);

        // 2. 企业名称
        Map<String, Object> item2 = new HashMap<>();
        item2.put("id", 269288);
        item2.put("name", "企业名称");
        item2.put("type", "1");
        item2.put("sensitiveLevel", null);
        item2.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item2.put("shareType", "2");
        item2.put("noneShare", null);
        item2.put("infoCode", "companyName");
        mockList.add(item2);

        // 3. 车架号
        Map<String, Object> item3 = new HashMap<>();
        item3.put("id", 269291);
        item3.put("name", "车架号");
        item3.put("type", "1");
        item3.put("sensitiveLevel", null);
        item3.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item3.put("shareType", "2");
        item3.put("noneShare", null);
        item3.put("infoCode", "vin");
        mockList.add(item3);

        // 4. 维修日期
        Map<String, Object> item4 = new HashMap<>();
        item4.put("id", 269294);
        item4.put("name", "维修日期");
        item4.put("type", "1");
        item4.put("sensitiveLevel", null);
        item4.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item4.put("shareType", "2");
        item4.put("noneShare", null);
        item4.put("infoCode", "repairDate");
        mockList.add(item4);

        // 5. 送修里程
        Map<String, Object> item5 = new HashMap<>();
        item5.put("id", 269297);
        item5.put("name", "送修里程");
        item5.put("type", "1");
        item5.put("sensitiveLevel", null);
        item5.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item5.put("shareType", "2");
        item5.put("noneShare", null);
        item5.put("infoCode", "repairMileage");
        mockList.add(item5);

        // 6. 故障描述
        Map<String, Object> item6 = new HashMap<>();
        item6.put("id", 269300);
        item6.put("name", "故障描述");
        item6.put("type", "1");
        item6.put("sensitiveLevel", null);
        item6.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item6.put("shareType", "2");
        item6.put("noneShare", null);
        item6.put("infoCode", "faultDescription");
        mockList.add(item6);

        // 7. 维修项目
        Map<String, Object> item7 = new HashMap<>();
        item7.put("id", 269303);
        item7.put("name", "维修项目");
        item7.put("type", "1");
        item7.put("sensitiveLevel", null);
        item7.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item7.put("shareType", "2");
        item7.put("noneShare", null);
        item7.put("infoCode", "repairName");
        mockList.add(item7);

        // 8. 配件名称
        Map<String, Object> item8 = new HashMap<>();
        item8.put("id", 269306);
        item8.put("name", "配件名称");
        item8.put("type", "1");
        item8.put("sensitiveLevel", null);
        item8.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item8.put("shareType", "2");
        item8.put("noneShare", null);
        item8.put("infoCode", "partsName");
        mockList.add(item8);

        // 9. 配件数量
        Map<String, Object> item9 = new HashMap<>();
        item9.put("id", 269309);
        item9.put("name", "配件数量");
        item9.put("type", "1");
        item9.put("sensitiveLevel", null);
        item9.put("sourceSystem", "湖北省道路运输四级协同管理与服务系统");
        item9.put("shareType", "2");
        item9.put("noneShare", null);
        item9.put("infoCode", "partsQuantity");
        mockList.add(item9);

        return mockList;
    }

    /**
     * 实现7天数据量查询接口调用
     */
    @Override
    public List<DataNum7DayItemVO> getDataNumBy7Day() {
        log.info("[getDataNumBy7Day][开始调用7天数据量查询接口]");

        try {
            // 1. 构建请求头：添加鉴权Token和 contentType
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", AUTH_TOKEN);
            headers.put("Content-Type", "application/json;charset=UTF-8");
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

            // 2. 动态拼接URL + 发起GET请求
            String requestUrl = BASE_PATH_APP + DATA_NUM_7DAY_SUFFIX;
            String response = HttpUtils.get(requestUrl, headers);
            if (response == null || response.trim().isEmpty()) {
                log.error("[getDataNumBy7Day][接口返回空响应]");
                throw new ServiceException("7天数据量查询接口返回空响应");
            }
            log.info("[getDataNumBy7Day][接口响应内容]：{}", response);

            // 3. 解析响应：将JSON转为DataNum7DayRespVO
            DataNum7DayRespVO respVO = JsonUtils.parseObject(response, DataNum7DayRespVO.class);
            if (respVO == null) {
                throw new ServiceException("7天数据量查询响应解析失败，格式非法");
            }

            // 4. 校验响应状态：确保success=true且code=200
            if (Boolean.FALSE.equals(respVO.getSuccess()) || respVO.getCode() != 200) { // 改为 != 比较
                String errorMsg = String.format("7天数据量查询失败：code=%s，message=%s，success=%s",
                        respVO.getCode(), respVO.getMessage(), respVO.getSuccess());
                log.error("[getDataNumBy7Day][{}]", errorMsg);
                throw new ServiceException(errorMsg);
            }

            // 5. 校验核心数据列表：避免data为null或空
            if (CollectionUtils.isEmpty(respVO.getData())) {
                log.warn("[getDataNumBy7Day][接口返回data列表为空]");
                throw new ServiceException("7天数据量查询无有效数据");
            }

            log.info("[getDataNumBy7Day][接口调用成功]，共获取{}天数据", respVO.getData().size());
            return respVO.getData();

        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("[getDataNumBy7Day][接口调用异常]", e);
            throw new ServiceException("7天数据量查询异常：" + e.getMessage());
        }
    }

    @Override
    public InfoDO getInterfaceByCatalogId(Long catalogId) {
        Long portalLoginUserId = getPortalLoginUserId();
        if (portalLoginUserId == null) {
            throw new ServiceException("请登录");
        }

        if (false) { // 实际权限校验逻辑
            throw new ServiceException("您的账号暂无权限，请先申请权限");
        }
        InfoDO infoDO = infoService.getInterfaceByCatalogId(catalogId);
        if (infoDO == null) {
            throw new ServiceException("该目录下暂无接口，请联系服务方添加接口");
        }
        return infoDO;
    }

    /**
     * 获取数据集信息
     */
    @Override
    public List<CataLogDataSetVO> getDataSetById(Long catalogId) {
        log.info("[getDataSetById][开始获取数据集信息](catalogId: {})", catalogId);

        // 1. 调用第三方接口获取数据源信息（动态拼接URL）
        Map<String, Object> dataSourceMap = getThirdPartyDataSource(catalogId);
        if (dataSourceMap == null || dataSourceMap.isEmpty()) {
            log.error("[getDataSetById][第三方接口返回的data字段为空](catalogId: {})", catalogId);
            throw new ServiceException("第三方接口未返回有效数据源信息");
        }

        // 2. 提取dataSourceId和dataSourceName
        String dataSourceId = getStringSafely(dataSourceMap, "dataSourceId").split(",")[2];
        String dataSourceName = getStringSafely(dataSourceMap, "dataSourceName");
        if (dataSourceId == null || dataSourceId.trim().isEmpty()) {
            log.error("[getDataSetById][数据源ID为空](catalogId: {}, dataSourceMap: {})",
                    catalogId, JsonUtils.toJsonString(dataSourceMap));
            throw new ServiceException("数据源ID为空，无法查询数据集");
        }

        // 3. 从数据库查询数据集(没有则新增，有则直接返回)
        try {
            List<CataLogDataSetVO> dataSetVOList = infoService.getDataSetById(catalogId, dataSourceId);
            //判断是否登录
            Long portalLoginUserId = getPortalLoginUserId();
            if (portalLoginUserId == null) {
                throw new ServiceException(500,"请登录");
            }
            //查询当前用户是否申请
            String Status = infoService.applicationStatus(portalLoginUserId,catalogId,"2");
            if (CollectionUtils.isEmpty(dataSetVOList)) {
                log.warn("[getDataSetById][该目录下无数据集信息，开始新增](catalogId: {}, dataSourceId: {})",
                        catalogId, dataSourceId);
                // 新增三条数据（XLSX/CSV/JSON三种格式）
                for (int i = 1; i < 4; i++) {
                    CataLogDataSetVO dataSetVO = new CataLogDataSetVO();
                    dataSetVO.setCatalogId(String.valueOf(catalogId));
                    dataSetVO.setDownloadType(String.valueOf(i));
                    dataSetVO.setNum(0L);
                    dataSetVO.setDataSourceId(dataSourceId);
                    dataSetVO.setDataSourceName(dataSourceName);

                    infoService.addDataSet(dataSetVO);
                }
                // 新增后重新查询
                dataSetVOList = infoService.getDataSetById(catalogId, dataSourceId);
            }

            // 补充数据源名称
            dataSetVOList.forEach(item -> item.setDataSourceName(dataSourceName));
            dataSetVOList.forEach(item -> item.setStatus(Status));
            log.info("[getDataSetById][成功获取数据集列表](catalogId: {}, 数据条数: {})",
                    catalogId, dataSetVOList.size());
            return dataSetVOList;

        } catch (Exception e) {
            log.error("[getDataSetById][查询数据库异常](catalogId: {}, dataSourceId: {})",
                    catalogId, dataSourceId, e);
            throw new ServiceException("查询数据集信息失败：" + e.getMessage());
        }
    }

    /**
     * 数据集下载实现：支持动态字段（适配thirdPartyData任意字段数量和名称）
     */
    @Override
    public void downloadDataSet(CataLogDataSetVO cataLogDataSetVO) {
        // 1. 基础校验（登录态、权限、参数）
        Long portalLoginUserId = getPortalLoginUserId();
        if (portalLoginUserId == null) {
            throw new ServiceException("请登录后再进行下载操作");
        }
        if (false) { // 实际权限校验逻辑
            throw new ServiceException("您的账号暂无该数据集的下载权限，请先申请权限");
        }
        validateDownloadParam(cataLogDataSetVO);

        try {
            // 2. 提取第三方接口所需的 tableId（从 dataSourceId 截取第三个值）
            String tableId = cataLogDataSetVO.getDataSourceId();
            log.info("[downloadDataSet][开始下载数据集](userId: {}, catalogId: {}, tableId: {}, 格式: {})",
                    portalLoginUserId, cataLogDataSetVO.getCatalogId(), tableId, cataLogDataSetVO.getDownloadType());

            // 3. 调用第三方接口获取原始数据（动态拼接URL）
            List<Map<String, Object>> thirdPartyData = getThirdPartyTableData(tableId);
            if (thirdPartyData == null || thirdPartyData.isEmpty()) {
                log.warn("[downloadDataSet][第三方接口返回空数据](tableId: {})", tableId);
                throw new ServiceException("当前数据集无数据可下载");
            }

            log.info("[downloadDataSet][使用动态字段测试数据](数据条数: {}, 字段数量: {})",
                    thirdPartyData.size(), thirdPartyData.get(0).keySet().size());

            // 4. 提取动态字段列表（从第一条数据获取所有字段，作为表头）
            if (thirdPartyData.isEmpty()) {
                throw new ServiceException("当前数据集无数据可下载");
            }
            List<String> dynamicFields = new ArrayList<>(thirdPartyData.get(0).keySet()); // 动态字段列表
            log.info("[downloadDataSet][动态提取字段列表]: {}", dynamicFields);

            // 5. 获取响应对象，设置下载头信息
            HttpServletResponse response = getCurrentResponse();
            String fileName = buildDownloadFileName(cataLogDataSetVO.getDataSourceName(), cataLogDataSetVO.getDownloadType());
            setDownloadResponseHeader(response, fileName, cataLogDataSetVO.getDownloadType());

            // 6. 按不同格式生成文件（适配动态字段）
            OutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();
                switch (cataLogDataSetVO.getDownloadType()) {
                    case "1": // XLSX 格式：动态生成表头和数据
                        writeDynamicXlsxToStream(thirdPartyData, dynamicFields, response, fileName);
                        break;
                    case "2": // CSV 格式：动态生成表头和数据
                        writeDynamicCsvToStream(thirdPartyData, dynamicFields, outputStream);
                        break;
                    case "3": // JSON 格式：原生支持动态字段
                        writeJsonToStream(thirdPartyData, outputStream);
                        break;
                    default:
                        throw new ServiceException("不支持的下载格式：" + cataLogDataSetVO.getDownloadType());
                }
                outputStream.flush();
            } finally {
                // 不手动关闭流，由Servlet容器管理
                if (outputStream != null) {
                    try {
                        outputStream.flush();
                    } catch (IOException e) {
                        log.warn("[downloadDataSet][流刷新异常]", e);
                    }
                }
            }

            // 7. 更新下载次数
            infoService.updateDownloadCount(cataLogDataSetVO);
            log.info("[downloadDataSet][下载成功](userId: {}, fileName: {}, 数据条数: {}, 字段数量: {})",
                    portalLoginUserId, fileName, thirdPartyData.size(), dynamicFields.size());

        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("[downloadDataSet][下载异常](catalogId: {}, 格式: {})",
                    cataLogDataSetVO.getCatalogId(), cataLogDataSetVO.getDownloadType(), e);
            throw new ServiceException("数据集下载失败：" + e.getMessage());
        }
    }

    @Override
    public Map<String, Integer> count() {
        Map<String, Integer> count = new HashMap<>();
        //获取数据目录总数
        Integer catalogCount = infoService.getCatalogCount();
        //获取数据接口总数
        Integer interfaceCount = infoService.getInterfaceCount();
        //获取数据集下载数量
        Integer DsCount = infoService.getDsCount(null);
        //获取需求申请数量
        Integer portCount = infoService.getApplicationCount();
        /**
         * 获取目录收藏数量
         */
        Integer collectCount = infoService.getCatalogCollectCount();
        count.put("catalogCount", catalogCount);
        count.put("interfaceCount", interfaceCount);
        count.put("DsCount", DsCount);
        count.put("portCount", portCount);
        count.put("collectCount", collectCount);
        log.info("[count][统计数据](catalogCount: {}, interfaceCount: {}, DsCount: {}, portCount: {}, collectCount: {})",
                catalogCount, interfaceCount, DsCount, portCount, collectCount);
        return count;
    }

    /**
     * 使用Apache POI直接生成Excel文件（修复版 - 兼容POI 5.x）
     */
    private void writeDynamicXlsxToStream(List<Map<String, Object>> thirdPartyData,
                                          List<String> dynamicFields,
                                          HttpServletResponse response,
                                          String fileName) throws IOException {
        if (thirdPartyData.isEmpty() || dynamicFields.isEmpty()) {
            log.warn("[writeDynamicXlsxToStream][数据或字段为空，无需生成XLSX]");
            return;
        }

        // 使用 try-with-resources 确保资源正确关闭
        try (SXSSFWorkbook workbook = new SXSSFWorkbook(100)) { // 设置行访问窗口大小为100
            Sheet sheet = workbook.createSheet("数据集");

            // 1. 创建表头
            Row headerRow = sheet.createRow(0);
            CellStyle headerStyle = workbook.createCellStyle();
            Font font = workbook.createFont();
            font.setBold(true);
            headerStyle.setFont(font);

            for (int i = 0; i < dynamicFields.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(dynamicFields.get(i));
                cell.setCellStyle(headerStyle);
            }

            // 2. 填充数据
            for (int rowNum = 0; rowNum < thirdPartyData.size(); rowNum++) {
                Map<String, Object> dataMap = thirdPartyData.get(rowNum);
                Row row = sheet.createRow(rowNum + 1);

                for (int colNum = 0; colNum < dynamicFields.size(); colNum++) {
                    String field = dynamicFields.get(colNum);
                    Object value = dataMap.getOrDefault(field, "");
                    Cell cell = row.createCell(colNum);

                    // 根据数据类型设置单元格值
                    if (value instanceof Number) {
                        cell.setCellValue(((Number) value).doubleValue());
                    } else if (value instanceof Date) {
                        cell.setCellValue((Date) value);
                        // 设置日期格式
                        CellStyle dateStyle = workbook.createCellStyle();
                        dateStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:mm:ss"));
                        cell.setCellStyle(dateStyle);
                    } else if (value instanceof Boolean) {
                        cell.setCellValue((Boolean) value);
                    } else {
                        cell.setCellValue(value != null ? value.toString() : "");
                    }
                }
            }

            // 3. 手动设置列宽（避免autoSizeColumn的问题）
            for (int i = 0; i < dynamicFields.size(); i++) {
                // 根据表头长度设置初始列宽
                int headerLength = dynamicFields.get(i).length();
                int columnWidth = Math.max(headerLength * 400, 3000); // 最小3000，约3个字符
                columnWidth = Math.min(columnWidth, 15000); // 最大15000，约15个字符
                sheet.setColumnWidth(i, columnWidth);
            }

            // 4. 写入响应流
            workbook.write(response.getOutputStream());

            log.debug("[writeDynamicXlsxToStream][POI动态XLSX生成成功](数据条数: {}, 表头字段: {})",
                    thirdPartyData.size(), dynamicFields);
        } catch (Exception e) {
            log.error("[writeDynamicXlsxToStream][POI生成Excel失败]", e);
            throw new ServiceException("生成Excel文件失败：" + e.getMessage());
        }
    }


    /**
     * 动态字段CSV生成：适配任意字段数量
     */
    private void writeDynamicCsvToStream(List<Map<String, Object>> thirdPartyData,
                                         List<String> dynamicFields,
                                         OutputStream outputStream) throws IOException {
        if (thirdPartyData.isEmpty() || dynamicFields.isEmpty()) {
            log.warn("[writeDynamicCsvToStream][数据或字段为空，无需生成CSV]");
            return;
        }

        // 1. 写入CSV表头（动态字段）
        String headLine = String.join(",", dynamicFields) + "\n";
        outputStream.write(headLine.getBytes(StandardCharsets.UTF_8));

        // 2. 写入CSV数据（按字段顺序遍历，适配动态字段）
        for (Map<String, Object> dataMap : thirdPartyData) {
            List<String> cellValues = new ArrayList<>();
            for (String field : dynamicFields) {
                // 获取字段值，空值处理为空白字符串
                Object value = dataMap.getOrDefault(field, "");
                String cellValue = value.toString();

                // CSV格式转义：处理包含逗号、引号、换行符的字段
                if (cellValue.contains(",") || cellValue.contains("\"") || cellValue.contains("\n") || cellValue.contains("\r")) {
                    cellValue = "\"" + cellValue.replace("\"", "\"\"") + "\""; // 双引号转义为两个双引号
                }
                cellValues.add(cellValue);
            }
            // 拼接一行数据并写入
            String dataLine = String.join(",", cellValues) + "\n";
            outputStream.write(dataLine.getBytes(StandardCharsets.UTF_8));
        }
        log.debug("[writeDynamicCsvToStream][动态CSV生成成功](数据条数: {}, 表头字段: {})",
                thirdPartyData.size(), dynamicFields);
    }

    /**
     * 生成JSON文件并写入流（原生支持动态字段）
     */
    private void writeJsonToStream(List<Map<String, Object>> data, OutputStream outputStream) throws JsonProcessingException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        // 格式化JSON输出，便于阅读
        String jsonStr = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
        outputStream.write(jsonStr.getBytes(StandardCharsets.UTF_8));
        log.debug("[writeJsonToStream][JSON生成成功](数据条数: {})", data.size());
    }

    /**
     * 校验下载参数合法性
     */
    private void validateDownloadParam(CataLogDataSetVO cataLogDataSetVO) {
        if (cataLogDataSetVO == null) {
            throw new ServiceException("下载参数不能为空");
        }
        if (cataLogDataSetVO.getCatalogId() == null || cataLogDataSetVO.getCatalogId().trim().isEmpty()) {
            throw new ServiceException("目录ID不能为空");
        }
        if (cataLogDataSetVO.getDataSourceId() == null || cataLogDataSetVO.getDataSourceId().trim().isEmpty()) {
            throw new ServiceException("数据源ID不能为空");
        }
        if (!"1".equals(cataLogDataSetVO.getDownloadType())
                && !"2".equals(cataLogDataSetVO.getDownloadType())
                && !"3".equals(cataLogDataSetVO.getDownloadType())) {
            throw new ServiceException("仅支持 XLSX(1)、CSV(2)、JSON(3) 格式下载");
        }
    }

    /**
     * 调用第三方接口获取表数据（动态拼接URL）
     */
    private List<Map<String, Object>> getThirdPartyTableData(String tableId) {
        try {
            // 1. 构建请求URL（动态拼接 + URL编码）
            String encodedTableId = URLEncoder.encode(tableId, StandardCharsets.UTF_8.name());
            String requestUrl = String.format("%s%s?tableId=%s",
                    BASE_PATH_APP, THIRD_PARTY_TABLE_DATA_SUFFIX, encodedTableId);
            log.debug("[getThirdPartyTableData][请求第三方接口](url: {})", requestUrl);

            // 2. 构建请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", AUTH_TOKEN);
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

            // 3. 发起GET请求
            String response = HttpUtils.get(requestUrl, headers);
            if (response == null || response.trim().isEmpty()) {
                log.error("[getThirdPartyTableData][接口返回空响应](tableId: {})", tableId);
                throw new ServiceException("第三方数据接口返回空响应");
            }

            // 4. 解析响应JSON
            Map<String, Object> responseMap = JsonUtils.parseObject(response, Map.class);
            if (responseMap == null) {
                throw new ServiceException("第三方数据接口响应格式非法");
            }

            // 5. 校验响应状态
            Boolean success = (Boolean) responseMap.get("success");
            Integer code = getIntegerSafely(responseMap, "code");
            if (Boolean.FALSE.equals(success) || (code != null && code != 200)) {
                String errorMsg = String.format("第三方数据接口调用失败: code=%s, msg=%s, success=%s",
                        code, responseMap.get("message"), success);
                log.error("[getThirdPartyTableData][{}](tableId: {})", errorMsg, tableId);
                throw new ServiceException("获取数据集原始数据失败：" + errorMsg);
            }

            // 6. 提取data字段
            Object dataObj = responseMap.get("data");
            if (!(dataObj instanceof List)) {
                throw new ServiceException("第三方接口返回的data字段不是列表格式");
            }
            return (List<Map<String, Object>>) dataObj;

        } catch (Exception e) {
            log.error("[getThirdPartyTableData][调用异常](tableId: {})", tableId, e);
            throw new ServiceException("获取第三方数据集失败：" + e.getMessage());
        }
    }

    /**
     * 获取当前请求的响应对象
     */
    private HttpServletResponse getCurrentResponse() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null || attributes.getResponse() == null) {
            throw new ServiceException("无法获取当前请求的响应对象，下载失败");
        }
        return attributes.getResponse();
    }

    /**
     * 构建下载文件名
     */
    private String buildDownloadFileName(String dataSourceName, String downloadType) {
        String safeDataSourceName = (dataSourceName == null || dataSourceName.trim().isEmpty())
                ? "未命名数据集"
                : dataSourceName.trim().replaceAll("[\\\\/:*?\"<>|]", "_");
        String suffix;
        switch (downloadType) {
            case "1":
                suffix = "xlsx";
                break;
            case "2":
                suffix = "csv";
                break;
            case "3":
                suffix = "json";
                break;
            default:
                suffix = "data";
                break;
        }
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        return String.format("%s_%s.%s", safeDataSourceName, timestamp, suffix);
    }

    /**
     * 设置下载响应头
     */
    private void setDownloadResponseHeader(HttpServletResponse response, String fileName, String downloadType) throws IOException {
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
        String contentType;
        switch (downloadType) {
            case "1":
                contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                break;
            case "2":
                contentType = "text/csv;charset=UTF-8";
                break;
            case "3":
                contentType = "application/json;charset=UTF-8";
                break;
            default:
                contentType = "application/octet-stream";
                break;
        }

        response.setContentType(contentType);
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition",
                String.format("attachment;filename=\"%s\";filename*=UTF-8''%s", encodedFileName, encodedFileName));
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
    }

    /**
     * 封装第三方数据源接口：仅返回响应中的data字段（动态拼接URL）
     */
    private Map<String, Object> getThirdPartyDataSource(Long catalogId) {
        log.info("[getThirdPartyDataSource][开始调用第三方数据源接口](catalogId: {})", catalogId);

        if (catalogId == null) {
            log.error("[getThirdPartyDataSource][目录ID为空]");
            throw new ServiceException("目录ID不能为空");
        }

        try {
            // 动态拼接请求URL
            String requestUrl = String.format("%s%s?catalogId=%s",
                    BASE_PATH_COMM, THIRD_PARTY_DATA_SOURCE_SUFFIX, catalogId);
            log.info("[getThirdPartyDataSource][请求地址](url: {})", requestUrl);

            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");
            headers.put("Authorization", AUTH_TOKEN);
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

            String response = HttpUtils.get(requestUrl, headers);
            if (response == null || response.trim().isEmpty()) {
                log.error("[getThirdPartyDataSource][接口返回空响应](catalogId: {})", catalogId);
                throw new ServiceException("第三方数据源接口返回空响应");
            }
            log.debug("[getThirdPartyDataSource][接口响应](response: {})", response);

            Map<String, Object> responseMap = JsonUtils.parseObject(response, Map.class);
            if (responseMap == null) {
                throw new ServiceException("第三方数据源接口响应格式非法");
            }

            Integer code = getIntegerSafely(responseMap, "code");
            Boolean success = (Boolean) responseMap.get("success");
            if (code == null || code != 200 || Boolean.FALSE.equals(success)) {
                String errorMsg = String.format("第三方数据源接口调用失败: code=%s, msg=%s, success=%s",
                        code, responseMap.get("msg"), success);
                log.error("[getThirdPartyDataSource][{}](catalogId: {})", errorMsg, catalogId);
                throw new ServiceException(errorMsg);
            }

            Map<String, Object> dataMap = (Map<String, Object>) responseMap.get("data");
            log.info("[getThirdPartyDataSource][成功提取data字段](catalogId: {})", catalogId);
            return dataMap;

        } catch (Exception e) {
            log.error("[getThirdPartyDataSource][接口调用异常](catalogId: {})", catalogId, e);
            throw new ServiceException("获取数据源信息失败：" + e.getMessage());
        }
    }

    /**
     * 转换目录详情数据为VO
     */
    @SuppressWarnings("unchecked")
    private ResourceDirectoryVO convertToResourceDirectoryVO(Map<String, Object> dataMap) {
        ResourceDirectoryVO vo = new ResourceDirectoryVO();

        vo.setCatalogId(getLongSafely(dataMap, "catalogId"));
        vo.setCatalogCode(getStringSafely(dataMap, "catalogCode"));
        vo.setMenuName(getStringSafely(dataMap, "menuName"));
        vo.setMenuId(getLongSafely(dataMap, "menuId"));
        vo.setCatalogName(getStringSafely(dataMap, "catalogName"));
        vo.setShareProperty(getStringSafely(dataMap, "shareProperty"));
        vo.setApplyNum(getIntegerSafely(dataMap, "applyNum"));
        vo.setViewNum(getIntegerSafely(dataMap, "viewNum"));
        vo.setIsMatter(getIntegerSafely(dataMap, "isMatter"));
        vo.setMatterId(getIntegerSafely(dataMap, "matterId"));
        vo.setMatterName(getStringSafely(dataMap, "matterName"));
        vo.setMatterCode(getStringSafely(dataMap, "matterCode"));
        vo.setMatterResult(getStringSafely(dataMap, "matterResult"));
        vo.setDeptName(getStringSafely(dataMap, "deptName"));
        vo.setDeptId(getLongSafely(dataMap, "deptId"));
        vo.setUpdateTime(getStringSafely(dataMap, "updateTime"));
        vo.setIsPermit(getIntegerSafely(dataMap, "isPermit"));
        vo.setIsCollection(getIntegerSafely(dataMap, "isCollection"));
        vo.setApplyScene(getStringSafely(dataMap, "applyScene"));
        vo.setChannel(getStringSafely(dataMap, "channel"));
        vo.setDomain(getStringSafely(dataMap, "domain"));
        vo.setPeriodType(getStringSafely(dataMap, "periodType"));
        vo.setAbstractInfo(getStringSafely(dataMap, "abstractInfo"));
        vo.setUseScore(getIntegerSafely(dataMap, "useScore"));
        vo.setBusinessDomain(getStringSafely(dataMap, "businessDomain"));
        vo.setSubjectType(getStringSafely(dataMap, "subjectType"));
        vo.setSubjectFeature(getStringSafely(dataMap, "subjectFeature"));
        vo.setIndustryClass(getStringSafely(dataMap, "industryClass"));
        vo.setBusinessClass(getStringSafely(dataMap, "businessClass"));
        vo.setManageObjClass(getStringSafely(dataMap, "manageObjClass"));
        vo.setTopicClass(getStringSafely(dataMap, "topicClass"));
        vo.setInfoCategoryClass(getStringSafely(dataMap, "infoCategoryClass"));
        vo.setFromSystem(getStringSafely(dataMap, "fromSystem"));
        vo.setIrfClass(getStringSafely(dataMap, "irfClass"));
        vo.setIrfType(getStringSafely(dataMap, "irfType"));
        vo.setSrcdb(getStringSafely(dataMap, "srcdb"));
        vo.setIrCode(getStringSafely(dataMap, "irCode"));
        vo.setTableEnname(getStringSafely(dataMap, "tableEnname"));
        vo.setIrProvideCode(getStringSafely(dataMap, "irProvideCode"));

        vo.setTabResource((Map<String, Object>) dataMap.get("tabResource"));
        vo.setFileResource((Map<String, Object>) dataMap.get("fileResource"));
        vo.setApiResource((Map<String, Object>) dataMap.get("apiResource"));

        return vo;
    }

    /**
     * 转换目录信息项为VO
     */
    private CatalogInfoItemVO convertToCatalogInfoItemVO(Map<String, Object> itemMap) {
        CatalogInfoItemVO itemVO = new CatalogInfoItemVO();
        itemVO.setId(getLongSafely(itemMap, "id"));
        itemVO.setInfoCode(getStringSafely(itemMap, "infoCode"));
        itemVO.setName(getStringSafely(itemMap, "name"));
        itemVO.setNoneShare(getStringSafely(itemMap, "noneShare"));
        itemVO.setSensitiveLevel(getStringSafely(itemMap, "sensitiveLevel"));
        itemVO.setShareType(getStringSafely(itemMap, "shareType"));
        itemVO.setSourceSystem(getStringSafely(itemMap, "sourceSystem"));
        itemVO.setType(getStringSafely(itemMap, "type"));
        return itemVO;
    }

    /**
     * 安全获取String类型值
     */
    private String getStringSafely(Map<String, Object> dataMap, String key) {
        Object value = dataMap.get(key);
        return value != null ? value.toString() : null;
    }

    /**
     * 安全获取Long类型值
     */
    private Long getLongSafely(Map<String, Object> dataMap, String key) {
        Object value = dataMap.get(key);
        if (value instanceof Number) {
            return ((Number) value).longValue();
        } else if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                log.warn("[getLongSafely][字段转换Long失败](key: {}, value: {})", key, value, e);
                return null;
            }
        }
        return null;
    }

    /**
     * 安全获取Integer类型值
     */
    private Integer getIntegerSafely(Map<String, Object> dataMap, String key) {
        Object value = dataMap.get(key);
        if (value instanceof Number) {
            return ((Number) value).intValue();
        } else if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                log.warn("[getIntegerSafely][字段转换Integer失败](key: {}, value: {})", key, value, e);
                return null;
            }
        }
        return null;
    }


    /**
     * 用于封装特殊目录ID的配置信息
     */
    private static class SpecialCatalogConfig {
        private final Map<String, Object> mockDataMap;
        private final Map<String, Object> otherResource;
        private final String interfaceStatus;

        public SpecialCatalogConfig(Map<String, Object> mockDataMap, Map<String, Object> otherResource, String interfaceStatus) {
            this.mockDataMap = mockDataMap;
            this.otherResource = otherResource;
            this.interfaceStatus = interfaceStatus;
        }

        // Getters
        public Map<String, Object> getMockDataMap() { return mockDataMap; }
        public Map<String, Object> getOtherResource() { return otherResource; }
        public String getInterfaceStatus() { return interfaceStatus; }
    }

    /**
     * 特殊目录ID的配置映射表
     * 键: catalogId
     * 值: 对应的特殊配置
     */
    private static final Map<Long, SpecialCatalogConfig> SPECIAL_CATALOG_CONFIGS;

    static {
        SPECIAL_CATALOG_CONFIGS = new HashMap<>();

        // --- 运单信息查询服务接口 ---
        Map<String, Object> dataMap77617050 = new HashMap<>();
        dataMap77617050.put("catalogId", 77617050L);
        dataMap77617050.put("catalogCode", "102002000/673");
        dataMap77617050.put("menuName", "省道路运输事业发展中心");
        dataMap77617050.put("menuId", 34942010);
        dataMap77617050.put("catalogName", "运单信息查询服务接口");
        dataMap77617050.put("shareProperty", "2");
        dataMap77617050.put("applyNum", 0);
        dataMap77617050.put("viewNum", 10);
        dataMap77617050.put("isMatter", 0);
        dataMap77617050.put("matterId", 0);
        dataMap77617050.put("matterName", null);
        dataMap77617050.put("matterCode", null);
        dataMap77617050.put("matterResult", null);
        dataMap77617050.put("deptName", "省道路运输事业发展中心");
        dataMap77617050.put("deptId", 538);
        dataMap77617050.put("updateTime", "2025-11-06 12:53:32");
        dataMap77617050.put("isPermit", 0);
        dataMap77617050.put("isCollection", 0);
        dataMap77617050.put("applyScene", null);
        dataMap77617050.put("channel", null);
        dataMap77617050.put("domain", null);
        dataMap77617050.put("periodType", null);
        dataMap77617050.put("abstractInfo", "");
        dataMap77617050.put("useScore", "0");
        dataMap77617050.put("businessDomain", "dlys");
        dataMap77617050.put("subjectType", "jcjt");
        dataMap77617050.put("subjectFeature", "yzgjl");
        dataMap77617050.put("industryClass", "dljt");
        dataMap77617050.put("businessClass", "dlhygl");
        dataMap77617050.put("manageObjClass", "yszb");
        dataMap77617050.put("topicClass", "ybzwgl");
        dataMap77617050.put("infoCategoryClass", "CA");
        dataMap77617050.put("fromSystem", "21");
        dataMap77617050.put("irfClass", "post");
        dataMap77617050.put("irfType", "接口");
        dataMap77617050.put("srcdb", "车辆送修信息查询服务接口");
        dataMap77617050.put("irCode", "11420000011043276100/012TL01OATACA0012");
        dataMap77617050.put("tableEnname", " getShippingNote");
        dataMap77617050.put("irProvideCode", "XXXXXXXXXXXXXXSS");
        dataMap77617050.put("tabResource", new HashMap<>());
        dataMap77617050.put("fileResource", new HashMap<>());
        dataMap77617050.put("apiResource", new HashMap<>());
        dataMap77617050.put("average", null);

        Map<String, Object> otherResource77617050 = new HashMap<>();
        otherResource77617050.put("1", "模拟的ETL状态");
        otherResource77617050.put("2", 5);
        otherResource77617050.put("3", 2);

        SPECIAL_CATALOG_CONFIGS.put(77617050L, new SpecialCatalogConfig(
                dataMap77617050,
                otherResource77617050,
                "模拟的接口审核状态"
        ));

        // --- 司机信息查询服务接口 ---
        Map<String, Object> dataMap77398360 = new HashMap<>();
        dataMap77398360.put("catalogId", 77398360L);
        dataMap77398360.put("catalogCode", "102002000/671");
        dataMap77398360.put("menuName", "省道路运输事业发展中心");
        dataMap77398360.put("menuId", 34942010);
        dataMap77398360.put("catalogName", "司机信息查询服务接口");
        dataMap77398360.put("shareProperty", "2");
        dataMap77398360.put("applyNum", 0);
        dataMap77398360.put("viewNum", 2);
        dataMap77398360.put("isMatter", 0);
        dataMap77398360.put("matterId", 0);
        dataMap77398360.put("matterName", null);
        dataMap77398360.put("matterCode", null);
        dataMap77398360.put("matterResult", null);
        dataMap77398360.put("deptName", "省道路运输事业发展中心");
        dataMap77398360.put("deptId", 538);
        dataMap77398360.put("updateTime", "2025-11-06 12:53:31");
        dataMap77398360.put("isPermit", 0);
        dataMap77398360.put("isCollection", 0);
        dataMap77398360.put("applyScene", null);
        dataMap77398360.put("channel", null);
        dataMap77398360.put("domain", null);
        dataMap77398360.put("periodType", null);
        dataMap77398360.put("abstractInfo", "");
        dataMap77398360.put("useScore", "0");
        dataMap77398360.put("businessDomain", "dlys");
        dataMap77398360.put("subjectType", "jcjt");
        dataMap77398360.put("subjectFeature", "yzgjl");
        dataMap77398360.put("industryClass", "dljt");
        dataMap77398360.put("businessClass", "dlhygl");
        dataMap77398360.put("manageObjClass", "yszb");
        dataMap77398360.put("topicClass", "ybzwgl");
        dataMap77398360.put("infoCategoryClass", "CA");
        dataMap77398360.put("fromSystem", "21");
        dataMap77398360.put("irfClass", "post");
        dataMap77398360.put("irfType", "接口");
        dataMap77398360.put("srcdb", "车辆送修信息查询服务接口");
        dataMap77398360.put("irCode", "11420000011043276100/012TL01OATACA0001");
        dataMap77398360.put("tableEnname", "getDriverInfo");
        dataMap77398360.put("irProvideCode", "XXXXXXXXXXXXXXSS");
        dataMap77398360.put("tabResource", new HashMap<>());
        dataMap77398360.put("fileResource", new HashMap<>());
        dataMap77398360.put("apiResource", new HashMap<>());
        dataMap77398360.put("average", null);

        Map<String, Object> otherResource77398360 = new HashMap<>();
        otherResource77398360.put("1", "模拟的ETL状态_77398360");
        otherResource77398360.put("2", 10);
        otherResource77398360.put("3", 3);

        SPECIAL_CATALOG_CONFIGS.put(77398360L, new SpecialCatalogConfig(
                dataMap77398360,
                otherResource77398360,
                "模拟的接口审核状态_77398360"
        ));


        // --- 车辆信息查询服务接口---
        Map<String, Object> dataMap77482490 = new HashMap<>();
        dataMap77482490.put("catalogId", 77482490L);
        dataMap77482490.put("catalogCode", "102002000/672");
        dataMap77482490.put("menuName", "省道路运输事业发展中心");
        dataMap77482490.put("menuId", 34942010);
        dataMap77482490.put("catalogName", "车辆信息查询服务接口");
        dataMap77482490.put("shareProperty", "2");
        dataMap77482490.put("applyNum", 0);
        dataMap77482490.put("viewNum", 3);
        dataMap77482490.put("isMatter", 0);
        dataMap77482490.put("matterId", 0);
        dataMap77482490.put("matterName", null);
        dataMap77482490.put("matterCode", null);
        dataMap77482490.put("matterResult", null);
        dataMap77482490.put("deptName", "省道路运输事业发展中心");
        dataMap77482490.put("deptId", 538);
        dataMap77482490.put("updateTime", "2025-11-06 12:53:31");
        dataMap77482490.put("isPermit", 0);
        dataMap77482490.put("isCollection", 0);
        dataMap77482490.put("applyScene", null);
        dataMap77482490.put("channel", null);
        dataMap77482490.put("domain", null);
        dataMap77482490.put("periodType", null);
        dataMap77482490.put("abstractInfo", "");
        dataMap77482490.put("useScore", "0");
        dataMap77482490.put("businessDomain", "dlys");
        dataMap77482490.put("subjectType", "jcjt");
        dataMap77482490.put("subjectFeature", "yzgjl");
        dataMap77482490.put("industryClass", "dljt");
        dataMap77482490.put("businessClass", "dlhygl");
        dataMap77482490.put("manageObjClass", "yszb");
        dataMap77482490.put("topicClass", "ybzwgl");
        dataMap77482490.put("infoCategoryClass", "CA");
        dataMap77482490.put("fromSystem", "21");
        dataMap77482490.put("irfClass", "post");
        dataMap77482490.put("irfType", "接口");
        dataMap77482490.put("srcdb", "车辆送修信息查询服务接口");
        dataMap77482490.put("irCode", "11420000011043276100/012TL01OATACA0001");
        dataMap77482490.put("tableEnname", "getVehicleInfo");
        dataMap77482490.put("irProvideCode", "XXXXXXXXXXXXXXSS");
        dataMap77482490.put("tabResource", new HashMap<>());
        dataMap77482490.put("fileResource", new HashMap<>());
        dataMap77482490.put("apiResource", new HashMap<>());
        dataMap77482490.put("average", null);

        Map<String, Object> otherResource77482490 = new HashMap<>();
        otherResource77482490.put("1", "模拟的ETL状态_77482490");
        otherResource77482490.put("2", 8); // 模拟数据集数量
        otherResource77482490.put("3", 4); // 模拟接口数量

        SPECIAL_CATALOG_CONFIGS.put(77482490L, new SpecialCatalogConfig(
                dataMap77482490,
                otherResource77482490,
                "模拟的接口审核状态_77482490"
        ));

        // 车辆送修信息查询服务接口---
        Map<String, Object> dataMap77303100 = new HashMap<>();
        dataMap77303100.put("catalogId", 77303100L);
        dataMap77303100.put("catalogCode", "102002000/670");
        dataMap77303100.put("menuName", "省道路运输事业发展中心");
        dataMap77303100.put("menuId", 34942010);
        dataMap77303100.put("catalogName", "车辆送修信息查询服务接口");
        dataMap77303100.put("shareProperty", "2");
        dataMap77303100.put("applyNum", 0);
        dataMap77303100.put("viewNum", 1);
        dataMap77303100.put("isMatter", 0);
        dataMap77303100.put("matterId", 0);
        dataMap77303100.put("matterName", null);
        dataMap77303100.put("matterCode", null);
        dataMap77303100.put("matterResult", null);
        dataMap77303100.put("deptName", "省道路运输事业发展中心");
        dataMap77303100.put("deptId", 538);
        dataMap77303100.put("updateTime", "2025-11-06 12:53:30");
        dataMap77303100.put("isPermit", 0);
        dataMap77303100.put("isCollection", 0);
        dataMap77303100.put("applyScene", null);
        dataMap77303100.put("channel", null);
        dataMap77303100.put("domain", null);
        dataMap77303100.put("periodType", null);
        dataMap77303100.put("abstractInfo", "");
        dataMap77303100.put("useScore", "0");
        dataMap77303100.put("businessDomain", "dlys");
        dataMap77303100.put("subjectType", "jcjt");
        dataMap77303100.put("subjectFeature", "yzgjl");
        dataMap77303100.put("industryClass", "dljt");
        dataMap77303100.put("businessClass", "dlhygl");
        dataMap77303100.put("manageObjClass", "yszb");
        dataMap77303100.put("topicClass", "ybzwgl");
        dataMap77303100.put("infoCategoryClass", "CA");
        dataMap77303100.put("fromSystem", "21");
        dataMap77303100.put("irfClass", "post");
        dataMap77303100.put("irfType", "接口");
        dataMap77303100.put("srcdb", "车辆送修信息查询服务接口");
        dataMap77303100.put("irCode", "11420000011043276100/012TL01OATACA0001");
        dataMap77303100.put("tableEnname", "getCarRepairInfo");
        dataMap77303100.put("irProvideCode", "XXXXXXXXXXXXXXSS");
        dataMap77303100.put("tabResource", new HashMap<>());
        dataMap77303100.put("fileResource", new HashMap<>());
        dataMap77303100.put("apiResource", new HashMap<>());
        dataMap77303100.put("average", null);

        Map<String, Object> otherResource77303100 = new HashMap<>();
        otherResource77303100.put("1", "模拟的ETL状态_77303100");
        otherResource77303100.put("2", 3); // 模拟数据集数量
        otherResource77303100.put("3", 1); // 模拟接口数量

        SPECIAL_CATALOG_CONFIGS.put(77303100L, new SpecialCatalogConfig(
                dataMap77303100,
                otherResource77303100,
                "模拟的接口审核状态_77303100"
        ));;


    }

    /**
     * 根据特殊配置构建 ResourceDirectoryVO 对象
     * @param config 特殊ID的配置信息
     * @return 构建好的 ResourceDirectoryVO
     */
    private ResourceDirectoryVO buildSpecialResourceDirectoryVO(SpecialCatalogConfig config) {
        ResourceDirectoryVO specialVO = convertToResourceDirectoryVO(config.getMockDataMap());
        specialVO.setOtherResource(config.getOtherResource());
        specialVO.setInterfaceStatus(config.getInterfaceStatus());
        return specialVO;
    }
}